//
// Created by Key-Box-Min on 31/05/2020.
//

#include "Object.h"
using namespace Lib;

Object::Object(Object* parent) : __parent(nullptr){
    if(parent == nullptr)installHandler(this);
    else setParent(parent);
}

Object::~Object() {
    delete_begin();
    Object* son = nullptr;
    while (__sons.getOne(son))delete son;
}

void Object::delete_begin() {
    if(__parent == nullptr)uinstallHandler(this);
    else{
        Object* p = __parent;
        p->__sons.lock()->erase(this);
        while (isUse())std::this_thread::yield();
    }
}

void Object::setParent(Object* parent){
    if(__parent == parent)return;

    if(__parent != nullptr){
        Object* p = __parent;
        p->__sons.lock()->erase(this);
    }else{
        uinstallHandler(this);
    }

    if(parent != nullptr){
        parent->__sons.lock()->insert(this);
    }else{
        installHandler(this);
    }

    __parent = parent;
}

bool Object::hasSon(Object *son) {return __sons.lock()->contains(this);}

void Object::event(EventAgent& event) {
    if(event->getType() == StartEvent::type()){
        emit(loop_start);
    }else if(event->getType() == StopEvent::type()){
        emit(loop_stop);
    }
    uint64_t index = 0;
    Object* obj_p = nullptr;
    while (__sons.ergodic_at(index++,obj_p))
        obj_p->onEvent(event);
    EventLoop::EventHandler::event(event);
}

bool Object::filter(EventAgent& event) {
    uint64_t index = 0;
    Object* obj_p = nullptr;
    while (__sons.ergodic_at(index++,obj_p))
        if(obj_p->onFilter(event))return true;
    return EventLoop::EventHandler::filter(event);
}

EventLoop*& Object::loop() {
    if(__parent == nullptr)return EventDriver::loop();
    return (*__parent).loop();
}

void Object::setLoop(EventLoop *loop) {
    if(__parent == nullptr){
        uinstallHandler(this);
        EventDriver::setLoop(loop);
        installHandler(this);
    }
}